require 'extract/rules/xml_rule'
require 'singleton'
require 'enum'
require 'csv'
require 'extract/rules/rule'


module Extract
  
  class YoutubeRules < Enum
    
    public
    
    #define de Brightkite extractions rules
    
    class FirstName < XMLRule
      def xpath
        "/entry/yt:firstName"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.first_name = val
      end
    end
    
    class LastName < XMLRule
      def xpath
        "/entry/yt:lastName"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.last_name = val
      end
    end
    
    class Age < XMLRule
      def xpath
        "/entry/yt:age"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.age = val.to_i
      end
    end
    
    class Gender < XMLRule
      def xpath
        "/entry/yt:gender"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.gender = val.eql?("m") ? "male" : "female"
      end
    end
    
    class FullLocation < XMLRule
      def xpath
        "/entry/yt:location"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.full_location = val
      end
    end
    
    class Local < FullLocation
      protected
      
      def preproces_val(val)
        d = val.match /.*,\b*(..)$/
        val.replace d.nil? ? "" : d[1]
        super val
      end
      
      def handle_val(val, dest_receiver)
        dest_receiver.locale_country = val.eql?("") ? nil : val
      end
    end
    
    class Locality < FullLocation
      protected
      
      def preproces_val(val)
        d = val.match /^([^,]*),.*/
        val.replace d.nil? ? "" : d[1]
        super val
      end
      
      def handle_val(val, dest_receiver)
        dest_receiver.locality = val.eql?("") ? nil : val
      end
    end
    
    class Hometown < XMLRule
      def xpath
        "/entry/yt:hometown"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.full_hometown = val
      end
    end
    
    #campo troppo lungo in molti casi (raccontao cosa fanno nella vita, vedere i cambiar quel)
    class Occupation < XMLRule
      def xpath
        "/entry/yt:occupation"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        if val.length >= 250 then
          dest_receiver.occupation = val[0..250]
        else
          dest_receiver.occupation = val
        end
      end
    end
    
    class MultiAttrRule < Rule
      
      def extract source_receiver, dest_receiver
        matchs = REXML::XPath.match source_receiver, xpath
        raise ArgumentError.new "matchs.length must be 0 or 1 instead of #{matchs.length}" if matchs.length > 1
        val = ""
        if matchs.length == 1 then
          val = matchs[0].text if matchs[0].instance_of? REXML::Element
          val = matchs[0].value if matchs[0].instance_of? REXML::Attribute
          val = matchs[0].string if matchs[0].instance_of? REXML::Comment
          vals = []
          val.split(/,|\n/).each { |m|
            v = ""
            v.replace m
            preproces_val v
            vals << v
#            puts "m: #{m}"
#            puts "v: #{v}"
         }
          
#          printf "vals:"
#          vals.each {|v| puts v}
#          
          if vals.size >= 1 then
            val.replace ""
            CSV::Writer.generate(val) { |csv| csv << vals }
          end
#          puts "val: #{val}"
          handle_val val, dest_receiver
        end        
        
      end
      
      def xpath
        raise NotImplementedError.new "Subclass must implents this method!!"
      end
      
      protected
      
      def preproces_val(val)
        val.strip!
        val.downcase!
      end
      
      def handle_val(val, dest_receiver)
        raise NotImplementedError.new "Subclass must implents this method!!"
      end
    end
    
    class Movies < MultiAttrRule
      def xpath
        "/entry/yt:movies"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.movies = val.eql?("") ? nil : val
      end
    end
    
    class Books < MultiAttrRule
      def xpath
        "/entry/yt:books"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.books = val.eql?("") ? nil : val
      end
    end
    
    class Music < MultiAttrRule
      def xpath
        "/entry/yt:music"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.music = val.eql?("") ? nil : val
      end
    end
    
    class Interests  < MultiAttrRule
      def xpath
        "/entry/yt:hobbies"
      end
      
      protected
      
      def handle_val(val, dest_receiver)
        dest_receiver.interests  = val.eql?("") ? nil : val
      end
    end
    
    protected
    
    def initialize
      super()
      @collections[:FirstName] = FirstName.instance
      @collections[:LastName] = LastName.instance
      @collections[:Age] = Age.instance
      @collections[:Gender] = Gender.instance
      @collections[:FullLocation] = FullLocation.instance
      @collections[:Local] = Local.instance
      @collections[:Locality] = Locality.instance
      @collections[:Hometown] = Hometown.instance
      @collections[:Occupation] = Occupation.instance
      @collections[:Interests] = Interests.instance
      @collections[:Music] = Music.instance
      @collections[:Books] = Books.instance
      @collections[:Movies] = Movies.instance
    end
    
  end
  
end